package org.duiduo.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.poi.excel.ExcelUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.base.Preconditions;
import lombok.extern.slf4j.Slf4j;
import org.duiduo.api.bean.UserAddressVO;
import org.duiduo.api.bean.UserVO;
import org.duiduo.api.request.UserFindPageRequest;
import org.duiduo.api.request.UserRegisterRequest;
import org.duiduo.api.response.Page;
import org.duiduo.api.response.Result;
import org.duiduo.constant.BaseConstants;
import org.duiduo.constant.ResponseConstants;
import org.duiduo.entity.User;
import org.duiduo.enums.UserRoleEnum;
import org.duiduo.exception.CustomException;
import org.duiduo.mapper.UserMapper;
import org.duiduo.service.UserService;
import org.duiduo.utils.ExportUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;

    @Autowired
    private BCryptPasswordEncoder cryptPasswordEncoder;

    /*@Override
    public User login(UserLoginRequest request) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", request.getUsername());
        queryWrapper.eq("password", request.getPassword());
        User res = userMapper.selectOne(queryWrapper);
        Preconditions.checkArgument(res != null, "用户名或密码错误");
        Preconditions.checkArgument(request.getRole().equals(res.getRole()), "角色类型不正确");
        // 生成token
        String token = TokenUtils.genToken(res);
        res.setToken(token);
        return res;
    }*/

    @Override
    public int register(UserRegisterRequest request) {
        LambdaQueryWrapper<User> wrapper = Wrappers.<User>lambdaQuery()
                .eq(User::getUsername, request.getUsername());
        User res = userMapper.selectOne(wrapper);
        Preconditions.checkArgument(res == null, ResponseConstants.Resp_2.RESP_00.getMessage());

        res = new User();
        BeanUtil.copyProperties(request, res, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        // 用户密码加密
        res.setPassword(cryptPasswordEncoder.encode(request.getPassword()));
        res.setRole(UserRoleEnum.NORMAL_USER.getRole());
        return userMapper.insert(res);
    }

    @Override
    public void save(UserVO userVO) {
        LambdaQueryWrapper<User> wrapper = Wrappers.<User>lambdaQuery()
                .eq(User::getUsername, userVO.getUsername());
        User res = userMapper.selectOne(wrapper);
        Preconditions.checkArgument(res == null, ResponseConstants.Resp_2.RESP_00.getMessage());

        res = new User();
        BeanUtil.copyProperties(userVO, res, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        res.setPassword(cryptPasswordEncoder.encode(BaseConstants.INITIAL_PASSWORD));
        userMapper.insert(res);
    }

    @Override
    public Page<UserVO> findPage(UserFindPageRequest request) {
        Page<UserVO> page = new Page<>();
        List<UserVO> userList = userMapper.findPage(request);
        int total = userMapper.total(request);
        page.setRecords(userList);
        page.setTotal(total);
        page.setPageNum(request.getPageNum());
        page.setPageSize(request.getPageSize());
        return page;
    }

    @Override
    public void update(UserVO userVO) {
        User oldUser = userMapper.selectById(userVO.getId());
        LambdaQueryWrapper<User> wrapper = Wrappers.<User>lambdaQuery()
                .eq(User::getUsername, userVO.getUsername());
        User res = userMapper.selectOne(wrapper);
        Preconditions.checkArgument(res == null || userVO.getUsername().equals(oldUser.getUsername()), "用户名已存在");

        res = new User();
        BeanUtil.copyProperties(userVO, res, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        res.setPassword(cryptPasswordEncoder.encode(userVO.getPassword()));
        userMapper.updateById(res);
    }

    @Override
    public void delete(Long id) {
        userMapper.deleteById(id);
    }

    @Override
    public User getById(Long id) {
        return userMapper.selectById(id);
    }

    @Override
    public List<User> selectAll() {
        return userMapper.selectList(null);
    }

    @Override
    public List<UserAddressVO> countAddress() {
        return userMapper.countAddress();
    }

    @Override
    public List<User> findAll(User user) {
        LambdaQueryWrapper<User> wrapper = Wrappers.<User>lambdaQuery();
        // 如果是普通用户
        if (UserRoleEnum.NORMAL_USER.getRole().equals(user.getRole())) {
            wrapper.eq(User::getId, user.getId());
        }
        return userMapper.selectList(wrapper);
    }

    @Override
    public void export(HttpServletResponse response) {
        List<Map<String, Object>> list = CollUtil.newArrayList();

        List<User> userList = selectAll();
        userList.forEach(user -> {
            Map<String, Object> row1 = new LinkedHashMap<>();
            row1.put("用户名", user.getUsername());
            row1.put("昵称", user.getNickname());
            row1.put("年龄", user.getAge());
            row1.put("性别", user.getSex());
            row1.put("地址", user.getAddress());
            if (user.getRole() == null) {
                row1.put("角色", "");
            } else {
                if (UserRoleEnum.ADMIN.getRole().equals(user.getRole())) {
                    row1.put("角色", UserRoleEnum.ADMIN.getRoleName());
                } else if (UserRoleEnum.NORMAL_USER.getRole().equals(user.getRole())) {
                    row1.put("角色", UserRoleEnum.NORMAL_USER.getRoleName());
                }
            }
            list.add(row1);
        });
        ExportUtil.export("用户信息", response, list);
    }

    @Override
    public Result upload(MultipartFile file) {
        try {
            InputStream inputStream = file.getInputStream();
            List<List<Object>> lists = ExcelUtil.getReader(inputStream).read(1);
            List<User> saveList = new ArrayList<>();
            for (List<Object> row : lists) {
                User user = new User();
                user.setUsername(row.get(0).toString());
                user.setNickname(row.get(1).toString());
                user.setAge(Integer.valueOf(row.get(2).toString()));
                user.setSex(row.get(3).toString());
                user.setAddress(row.get(4).toString());
                user.setRole(Integer.valueOf(row.get(5).toString()));
                user.setPassword(cryptPasswordEncoder.encode(BaseConstants.INITIAL_PASSWORD));
                saveList.add(user);
            }
            for (User user : saveList) {
                userMapper.insert(user);
            }
        } catch (Exception e) {
            throw new CustomException(ResponseConstants.Resp_1.RESP_03.getCode(), ResponseConstants.Resp_1.RESP_03.getMessage());
        }
        return Result.success();
    }

    @Override
    public User getByUsername(String username) {
        LambdaQueryWrapper<User> wrapper = Wrappers.<User>lambdaQuery()
                .eq(User::getUsername, username);
        return userMapper.selectOne(wrapper);
    }
}
